#ifndef MAPPING_H
#define MAPPING_H

const bool MUST_OVERLAP = 1;
const int NUM_TO_MAP = 5; 
const double SCORE_THRESH = 0.725;
const double VERIF_THRESH = PI/32;

//beliefs for relations:
//TODO: investigate alternatives for these weightings. Maybe all 1 to start.
const int B_LEFT = 2;
const int B_ABOVE = 10;
const int B_PAR = 5;
const int B_PERP = 2;
const int B_ADJ = 10;

Scalar lineColors[12] = {Scalar(0,0,0),//(235,175,0)
                      Scalar(200,255,255),//(0,237,252)
                      Scalar(255,0,0),//(151,62,158)
                      Scalar(0,255,0),//(80,171,24)
                      Scalar(0,0,255),//(0,0,0)
                      Scalar(230,230,0),
                      Scalar(0,255,255),
                      Scalar(255,50,255),
                      Scalar(0,128,0),
                      Scalar(0,64,128),
                      Scalar(173,0,173),
                      Scalar(0,128,255)
                                       }; //TODO: Add some more here? Need to keep them distinguishable.


//--------Class defs--------//

class MH{
    int n_lines;
    int *goalMappings;        //Numbers corresponding to LineGroups
    int *mappingEvidence;     //The amount of evidence for each mapping
    Line *g_lines;            //used in scoring MH
    Line *c_lines;            //       ''
    double score;
    public:
    MH(){}
    MH(int belief, Line g_line_0, Line g_line_1, Line c_line_0, Line c_line_1);
    MH(int *mappingEvidence, int* goalMappings, Line *g_lines, Line *c_line, int n_lines);
    int getN_lines();
    int *getMappings();
    int getMappingAt(int index);
    int *getAllEvidence();
    int getEvidenceAt(int index);
    Line *getAllG_lines();
    Line getG_lineAt(int index);
    Line *getAllC_lines();
    Line getC_lineAt(int index);
    double getScore();
    void scoreMH();
};

class GMap{
    int n_lines;
    double score;
    int *order_g;
    int *order_c;
    public:
    GMap(){}
    GMap(int n_lines, double MHScore, int *mappings); 
    int getN_lines();
    double getScore();
    int *getOrder_g();    
    int *getOrder_c();
};

//--------MATCH HYPOTHESIS--------//

double *calculateMeans(Line *lines, int n_lines);
bool canMerge(MH MH1, MH MH2);
MH mergeMHs(MH MH1, MH MH2);
bool compareMHs(MH MH1, MH MH2);
double *calculateRels(Line l, double *a_means);
double relOrientComp(double orientation1, double orientation2);
double relDistComp(double dist1, double dist2);
double relPosComp(double pos1, double pos2);
double lineSimScore(Line l_g, Line l_c, double *a_means_g, double *a_means_c);
int findMHs(MH *H, LineGroup L_g, LineGroup L_c);
int mergeMHs(MH *H, GMap *G, LineGroup L_g, LineGroup L_c);

//------------MAPPING-------------//

void drawGMaps(char *log_path, int numMaps, GMap *mappings, LineGroup L_g, LineGroup L_c, Mat cleanGoal, Mat cleanCurr);
#if 0
double getValByLongLine(int *goalOrder, int *currOrder, LineGroup L_g, LineGroup L_c);
double getValByBestMatch(int *goalOrder, int *currOrder, LineGroup L_g, LineGroup L_c);
double getAvgVal(int *order_g, int *order_c, LineGroup L_g, LineGroup L_c);
int getVerifiedBestMap(int numMaps, GMap *mappings, LineGroup L_g, LineGroup L_c, int method);
#endif

#endif
